#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->actionFilePath,&QAction::triggered,this,&MainWindow::viaFolderPath);
    connect(ui->btnFolder,&QToolButton::clicked,this,&MainWindow::viaFolderPath);

    connect(ui->actionRegistry,&QAction::triggered,this,&MainWindow::viaRegistry);
    connect(ui->btnRegistry,&QToolButton::clicked,this,&MainWindow::viaRegistry);

    connect(ui->actionDrivers,&QAction::triggered,this,&MainWindow::viaDrivers);
    connect(ui->btnDrivers,&QToolButton::clicked,this,&MainWindow::viaDrivers);

    connect(ui->actionServices,&QAction::triggered,this,&MainWindow::viaServices);
    connect(ui->btnServices,&QToolButton::clicked,this,&MainWindow::viaServices);

    connect(ui->actionSchedule,&QAction::triggered,this,&MainWindow::viaScheduledTasks);
    connect(ui->btnSchedule,&QToolButton::clicked,this,&MainWindow::viaScheduledTasks);

    connect(ui->actionDlls,&QAction::triggered,this,&MainWindow::viaKnownDlls);
    connect(ui->btnDlls,&QToolButton::clicked,this,&MainWindow::viaKnownDlls);

    connect(ui->actionHijack,&QAction::triggered,this,&MainWindow::viaImageHijack);
    connect(ui->btnImage,&QToolButton::clicked,this,&MainWindow::viaImageHijack);
    //将QString 类型转为 wchar*
//    QString filename="star.mp4";
//    qDebug()<<"QString len: "<<filename.length();
//    const WCHAR* const wstr=reinterpret_cast<const WCHAR*>(filename.utf16());
//    qDebug("wide form: %ls",wstr);
    //QString test="C:\\Users\\ShiyuanFir\\AppData\\Local\\WebEx\\ciscowebexstart.exe /daemon /from=autorun";  //有引号

    //QString test="sYstem32\\drivers\\bam.sys";

    QString test="@comres.dll,-2451";
    qDebug("raw version: %s",qPrintable(test));
    test=purePath(test);
    qDebug("final version: %s",qPrintable(test));

    QString testTime= gotoSingleFileTime(test);
    qDebug("time : %s",qPrintable(testTime));

    qDebug()<<"-------------";
    //testCert();
    qDebug()<<publisherName("C:\\WINDOWS\\system32\\SecurityHealthSystray.exe");

    qDebug()<<"-------------";
    QFileInfo filex("C:\\WINDOWS\\system32\\SecurityHealthSystray.exe");
    qDebug()<<filex.isFile();
    qDebug()<<filex.isDir();
}

MainWindow::~MainWindow()
{
    delete ui;

}

QString MainWindow::publisherName(const QString targetPath){
    // 目标：查看 target path: C:\Program Files (x86)\Microsoft Office\root\Office16\MSPUB.EXE 的数字证书
    GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
    WINTRUST_FILE_INFO sWintrustFileInfo;
    WINTRUST_DATA      sWintrustData;
    HRESULT            hr;


    memset((void*)&sWintrustFileInfo, 0x00, sizeof(WINTRUST_FILE_INFO));
    memset((void*)&sWintrustData, 0x00, sizeof(WINTRUST_DATA));

    sWintrustFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);

    //只修改这里即可
    sWintrustFileInfo.pcwszFilePath=reinterpret_cast<const WCHAR*>(targetPath.utf16());
    sWintrustFileInfo.hFile = NULL;

    sWintrustData.cbStruct = sizeof(WINTRUST_DATA);
    sWintrustData.dwUIChoice = WTD_UI_NONE;
    sWintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
    sWintrustData.dwUnionChoice = WTD_CHOICE_FILE;
    sWintrustData.pFile = &sWintrustFileInfo;
    sWintrustData.dwStateAction = WTD_STATEACTION_VERIFY;

    hr = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

    QString publisher="";
    if (TRUST_E_NOSIGNATURE == hr)
    {
        qDebug("No signature found on the file.");
        publisher+="(anonymous)";
    }
    else if (TRUST_E_BAD_DIGEST == hr)
    {
        qDebug("The signature of the file is invalid.");
        publisher+="(unverified)";
    }
    else if (TRUST_E_PROVIDER_UNKNOWN == hr)
    {
        qDebug("No trust provider on this machine can verify this type of files.");
        publisher+="(unverified)";
    }
    else if (S_OK != hr)
    {
        qDebug("WinVerifyTrust failed with error 0x%.8X", hr);
        publisher+="(unverified)";
    }
    else
    {
        qDebug("File signature is OK.");
        publisher+="(verified)";

        CRYPT_PROVIDER_DATA const *psProvData = NULL;
        CRYPT_PROVIDER_SGNR       *psProvSigner = NULL;
        CRYPT_PROVIDER_CERT       *psProvCert = NULL;
        FILETIME                   localFt;
        SYSTEMTIME                 sysTime;

        psProvData = WTHelperProvDataFromStateData(sWintrustData.hWVTStateData);
        if (psProvData)
        {
            psProvSigner = WTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA)psProvData, 0, FALSE, 0);
            if (psProvSigner)
            {
                FileTimeToLocalFileTime(&psProvSigner->sftVerifyAsOf, &localFt);
                FileTimeToSystemTime(&localFt, &sysTime);

                qDebug("Signature Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d.", sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);

                psProvCert = WTHelperGetProvCertFromChain(psProvSigner, 0);
                if (psProvCert)
                {
                    LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
                    if (szCertDesc)
                    {


                        QString rawOwner=QString("%1").arg(szCertDesc);
                        qDebug()<<"File signer: "<<rawOwner;

                        const int left=rawOwner.indexOf("O=");
                        const int maxpos=rawOwner.length()-1;
                        if(left>=0){
                            int right=left+2;
                            for(right=left+2;right<=maxpos;++right){
                                if(rawOwner[right]==",")break;
                            }
                            QString pureOwner=rawOwner.mid(left+2,right-left-2);
                            pureOwner.replace("\"","");
                            qDebug()<<"!!!real publisher: "<<pureOwner;
                            publisher+=pureOwner;
                        }
                        LocalFree(szCertDesc);
                    }
                }

                if (psProvSigner->csCounterSigners)
                {

                    // Timestamp information
                    FileTimeToLocalFileTime(&psProvSigner->pasCounterSigners[0].sftVerifyAsOf, &localFt);
                    FileTimeToSystemTime(&localFt, &sysTime);

                    qDebug("Timestamp Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d", sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
                    psProvCert = WTHelperGetProvCertFromChain(&psProvSigner->pasCounterSigners[0], 0);
                    if (psProvCert)
                    {
                        LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
                        if (szCertDesc)
                        {
                            qDebug("Timestamp Signer = %ls", szCertDesc);
                            LocalFree(szCertDesc);
                        }
                    }
                }
            }
        }
    }

    sWintrustData.dwUIChoice = WTD_UI_NONE;
    sWintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
    WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

    return  publisher;
}


void MainWindow::testCert(){
    // 目标：查看 C:\Program Files (x86)\Microsoft Office\root\Office16\MSPUB.EXE 的数字证书
    GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
    WINTRUST_FILE_INFO sWintrustFileInfo;
    WINTRUST_DATA      sWintrustData;
    HRESULT            hr;


    memset((void*)&sWintrustFileInfo, 0x00, sizeof(WINTRUST_FILE_INFO));
    memset((void*)&sWintrustData, 0x00, sizeof(WINTRUST_DATA));

    sWintrustFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);

    //只修改这里即可
    sWintrustFileInfo.pcwszFilePath = L"C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\MSPUB.EXE";
    sWintrustFileInfo.hFile = NULL;

    sWintrustData.cbStruct = sizeof(WINTRUST_DATA);
    sWintrustData.dwUIChoice = WTD_UI_NONE;
    sWintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
    sWintrustData.dwUnionChoice = WTD_CHOICE_FILE;
    sWintrustData.pFile = &sWintrustFileInfo;
    sWintrustData.dwStateAction = WTD_STATEACTION_VERIFY;

    hr = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

    if (TRUST_E_NOSIGNATURE == hr)
    {
        qDebug("No signature found on the file.");
    }
    else if (TRUST_E_BAD_DIGEST == hr)
    {
        qDebug("The signature of the file is invalid.");
    }
    else if (TRUST_E_PROVIDER_UNKNOWN == hr)
    {
        qDebug("No trust provider on this machine can verify this type of files.");
    }
    else if (S_OK != hr)
    {
        qDebug("WinVerifyTrust failed with error 0x%.8X", hr);
    }
    else
    {
        qDebug("File signature is OK.");

        // retreive the signer certificate and display its information
        CRYPT_PROVIDER_DATA const *psProvData = NULL;
        CRYPT_PROVIDER_SGNR       *psProvSigner = NULL;
        CRYPT_PROVIDER_CERT       *psProvCert = NULL;
        FILETIME                   localFt;
        SYSTEMTIME                 sysTime;

        psProvData = WTHelperProvDataFromStateData(sWintrustData.hWVTStateData);
        if (psProvData)
        {
            psProvSigner = WTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA)psProvData, 0, FALSE, 0);
            if (psProvSigner)
            {
                FileTimeToLocalFileTime(&psProvSigner->sftVerifyAsOf, &localFt);
                FileTimeToSystemTime(&localFt, &sysTime);

                qDebug("Signature Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d.", sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);

                psProvCert = WTHelperGetProvCertFromChain(psProvSigner, 0);
                if (psProvCert)
                {
                    LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
                    if (szCertDesc)
                    {

                        qDebug("File Signer = %ls", szCertDesc);
                        LocalFree(szCertDesc);
                    }
                }

                if (psProvSigner->csCounterSigners)
                {

                    // Timestamp information
                    FileTimeToLocalFileTime(&psProvSigner->pasCounterSigners[0].sftVerifyAsOf, &localFt);
                    FileTimeToSystemTime(&localFt, &sysTime);

                    qDebug("Timestamp Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d", sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
                    psProvCert = WTHelperGetProvCertFromChain(&psProvSigner->pasCounterSigners[0], 0);
                    if (psProvCert)
                    {
                        LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
                        if (szCertDesc)
                        {
                            qDebug("Timestamp Signer = %ls", szCertDesc);
                            LocalFree(szCertDesc);
                        }
                    }
                }
            }
        }
    }

    sWintrustData.dwUIChoice = WTD_UI_NONE;
    sWintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
    WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);


}

LPTSTR MainWindow::GetCertificateDescription(PCCERT_CONTEXT pCertCtx){
    DWORD dwStrType;
    DWORD dwCount;
    LPTSTR szSubjectRDN = NULL;

    dwStrType = CERT_X500_NAME_STR;
    dwCount = CertGetNameString(pCertCtx,
        CERT_NAME_RDN_TYPE,
        0,
        &dwStrType,
        NULL,
        0);
    if (dwCount)
    {
        szSubjectRDN = (LPTSTR)LocalAlloc(0, dwCount * sizeof(TCHAR));
        CertGetNameString(pCertCtx,
            CERT_NAME_RDN_TYPE,
            0,
            &dwStrType,
            szSubjectRDN,
            dwCount);
    }

    return szSubjectRDN;
}

QString MainWindow::purePath(const QString rawPath){
    QString formalPath="";
    formalPath+=rawPath;

    // 1、若有引号，则只取括号中的内容
    const int yin1=formalPath.indexOf("\"");
    if(yin1>=0){
        int yin2=yin1+1;
        const int maxpos=formalPath.length()-1;
        for(yin2=yin1+1;yin2<=maxpos;++yin2){
            if(formalPath[yin2]=="\""){
                break;
            }
        }
        if(yin2>maxpos)return "Unknown";

        formalPath=formalPath.mid(yin1+1,yin2-yin1-1);
    }

    // 2、去除首尾空格键，但是中间不能去除
    formalPath=formalPath.trimmed();

    // 若开头为@%systemroot%  ,-1 则要删除
    if(formalPath.startsWith("@")){
        const int douhao=formalPath.indexOf(",");
        if(douhao<0){
            formalPath.replace("@","");
        }
        else {
            formalPath=formalPath.mid(1,douhao-1);
        }
    }

    // 3、如果字符串中有%，说明要引入环境变量
    const int envpos1=formalPath.indexOf("%");
    if(envpos1>=0){
        int envpos2=envpos1+1;
        const int maxpos=formalPath.length()-1;
        for(envpos2=envpos1+1;envpos2<=maxpos;++envpos2){
            if(formalPath[envpos2]=="%") break;
        }
        if(envpos2>maxpos){
            return "Unknown";
        }


        QString envStr=formalPath.mid(envpos1+1,envpos2-envpos1-1);
        WCHAR envBuf[MAX_PATH]={0};
        ::GetEnvironmentVariableW(reinterpret_cast<const WCHAR*>(envStr.utf16()),envBuf,MAX_PATH);
        envStr=QString::fromWCharArray(envBuf);

        formalPath.replace(envpos1,envpos2-envpos1+1,envStr);
    }

    // 4、要忽略除了文件路径之外的所有参数 例如 -run /run
    const int maxpos=formalPath.length()-1;
    for (int i=0;i<=maxpos;++i) {
        if(formalPath[i]==" "&&i+1<=maxpos&&(formalPath[i+1]=="-"||formalPath[i+1]=="/")){
            formalPath=formalPath.left(i);
            break;
        }
    }

    // 5、如果没有首部“C:\”且system32/SysWOW64开头，则需要附加在头部"%systemroot%"
    if(formalPath.contains(":\\",Qt::CaseInsensitive)==false
            && formalPath.startsWith("\\")==false
            && (formalPath.contains("system32",Qt::CaseInsensitive)
                ||
                formalPath.contains("syswow64",Qt::CaseInsensitive))
            )
    {
        WCHAR envBuf[MAX_PATH]={0};
        ::GetEnvironmentVariableW(L"SystemRoot",envBuf,MAX_PATH);
        QString envStr=QString::fromWCharArray(envBuf);
        formalPath.prepend(envStr+"\\");
    }

    // 6、如果直接\\开头，则需要头部附加环境变量，并替换到原来字符串中
    if(formalPath.startsWith("\\",Qt::CaseInsensitive)){
        const int maxpos=formalPath.length()-1;
        int ending=1;
        for(ending=1;ending<=maxpos;++ending){
            if(formalPath[ending]=="\\")break;
        }

        WCHAR envBuf[MAX_PATH]={0};
        QString envStr=formalPath.mid(1,ending-1);
        qDebug()<<"huanjing!!!: "<<envStr;
        ::GetEnvironmentVariableW(reinterpret_cast<const WCHAR*>(envStr.utf16()),envBuf,MAX_PATH);
        //将QString 类型转为 wchar*
    //    QString filename="star.mp4";
    //    qDebug()<<"QString len: "<<filename.length();
    //    const WCHAR* const wstr=reinterpret_cast<const WCHAR*>(filename.utf16());
        QString rootMenu=QString::fromWCharArray(envBuf);
        formalPath.replace(0,envStr.length()+1,rootMenu);
    }

    return formalPath;
}

QString MainWindow::gotoSingleFileTime(const QString formalPath){
    const WCHAR* targetPath=reinterpret_cast<const WCHAR*>(formalPath.utf16());
    WIN32_FIND_DATA findFileData;
        HANDLE hFind;
        hFind = FindFirstFile(targetPath, &findFileData);
        if (hFind == INVALID_HANDLE_VALUE) {
            printf("No such path: %ls", targetPath);
            return "Unknown";
        }

        SYSTEMTIME st;
        FileTimeToSystemTime(
            &findFileData.ftLastWriteTime,
            &st
        );
//        WCHAR formalDate[MAX_PATH] = { 0 };
//        wsprintf(formalDate, L"%d/%d/%d %d:%d:%d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
//        qDebug("日期: %ls\n", formalDate);

        QString formalDate=QString("%1/%2/%3 %4:%5:%6").arg(st.wYear).arg(st.wMonth).arg(st.wDay).arg(st.wHour).arg(st.wMinute).arg(st.wSecond);
        //qDebug()<<"time: "<<formalDate;
        return  formalDate;
}

void MainWindow::viaImageHijack(){
    HKEY hkey=nullptr;
    long openResult=RegOpenKeyExW(
                HKEY_LOCAL_MACHINE,
                L"SOFTWARE\\Classes\\htmlfile\\shell\\open\\command",
                0,
                KEY_QUERY_VALUE,
                &hkey
                );
    if(openResult!=ERROR_SUCCESS){
        qDebug()<<"No such path. ";
        if(hkey!=nullptr){
            RegCloseKey(hkey);
        }
        return;
    }

    ui->tableWidget->clear();
    ui->tableWidget->setColumnCount(5);
    ui->tableWidget->setHorizontalHeaderLabels(
                QStringList()<<"name"<<"type"<<"data"<<"real path"<<"publisher"
                );
    ui->tableWidget->setRowCount(10);

    //遍历所有项目
    DWORD dwIndex=0;
    TCHAR valueName[MAX_PATH]={0};
    DWORD len=MAX_PATH;
    BYTE keyData[MAX_PATH]={0};
    DWORD dataLen=MAX_PATH;
    DWORD keyType=REG_DWORD;

    long traverseResult=RegEnumValue(
                hkey,dwIndex,valueName,
                &len,0,&keyType,
                keyData,&dataLen
                );

    int row=0;
    while (traverseResult==ERROR_SUCCESS) {
        //value name 记录项目名称,keydata记录数据,keyType记录类型
        //qDebug("key name: %ls, type: %u, data: %ls",valueName,keyType,keyData);

        QString formalName=QString::fromWCharArray(valueName);
        if(formalName==""){
            formalName="(default)";
        }
        QString formalData=QString::fromWCharArray((LPCTSTR)keyData);
        QString typeName;
        if(keyType==REG_SZ){
            typeName="REG_SZ";
        }
        else {
            typeName="unknown form";
        }
        qDebug()<<"name: "<<formalName<<", type: "<<typeName<<", data: "<<formalData;
        ui->tableWidget->setItem(row,0,new QTableWidgetItem(formalName));
        ui->tableWidget->setItem(row,1,new QTableWidgetItem(typeName));
        ui->tableWidget->setItem(row,2,new QTableWidgetItem(formalData));
        QString realPath=purePath(formalData);
        QString publisher=publisherName(realPath);
        ui->tableWidget->setItem(row,3,new QTableWidgetItem(realPath));
        ui->tableWidget->setItem(row,4,new QTableWidgetItem(publisher));

        row++;

        dwIndex++;
        len=MAX_PATH;
        dataLen=MAX_PATH;

        traverseResult=RegEnumValue(
                    hkey,dwIndex,valueName,
                    &len,0,&keyType,
                    keyData,&dataLen
                    );
    }

    if(hkey!=nullptr){
        RegCloseKey(hkey);
        qDebug()<<"I an all right";
    }
    ui->tableWidget->resizeColumnsToContents();
    ui->tableWidget->resizeRowsToContents();
}

void MainWindow::viaKnownDlls(){
    HKEY hkey=nullptr;
    long openResult=RegOpenKeyExW(
                HKEY_LOCAL_MACHINE,
                L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\KnownDLLs",
                0,
                KEY_QUERY_VALUE,
                &hkey
                );
    if(openResult!=ERROR_SUCCESS){
        qDebug()<<"No such path. ";
        if(hkey!=nullptr){
            RegCloseKey(hkey);
        }
        return;
    }

    ui->tableWidget->clear();
    ui->tableWidget->setColumnCount(4);
    ui->tableWidget->setHorizontalHeaderLabels(
                QStringList()<<"name"<<"type"<<"data"<<"real path"
                );
    ui->tableWidget->setRowCount(40);

    //可供选择的文件夹位置
    QStringList possibleLocality;
    possibleLocality<<"C:\\Windows\\SysWOW64"<<"C:\\Windows\\System32";

    //遍历所有项目
    DWORD dwIndex=0;
    TCHAR valueName[MAX_PATH]={0};
    DWORD len=MAX_PATH;
    BYTE keyData[MAX_PATH]={0};
    DWORD dataLen=MAX_PATH;
    DWORD keyType=REG_DWORD;

    long traverseResult=RegEnumValue(
                hkey,dwIndex,valueName,
                &len,0,&keyType,
                keyData,&dataLen
                );

    int row=0;
    while (traverseResult==ERROR_SUCCESS) {
        //value name 记录项目名称,keydata记录数据,keyType记录类型
        //qDebug("key name: %ls, type: %u, data: %ls",valueName,keyType,keyData);

        QString formalName=QString::fromWCharArray(valueName);
        QString formalData=QString::fromWCharArray((LPCTSTR)keyData);
        QString typeName;
        if(keyType==REG_SZ){
            typeName="REG_SZ";
        }
        else {
            typeName="unknown form";
        }
        qDebug()<<"name: "<<formalName<<", type: "<<typeName<<", data: "<<formalData;
        ui->tableWidget->setItem(row,0,new QTableWidgetItem(formalName));
        ui->tableWidget->setItem(row,1,new QTableWidgetItem(typeName));
        ui->tableWidget->setItem(row,2,new QTableWidgetItem(formalData));

        //查找dll文件所在文件夹路径
        QString realPath="unknown";
        for(int k=0;k<=possibleLocality.length()-1;++k){
            QString tmp=possibleLocality.at(k)+"\\"+formalData;
            qDebug()<<"$$$$$$"<<tmp;
            QFileInfo filex(tmp);
            if(filex.isFile()){
                realPath=tmp;
                break;
            }
        }
        ui->tableWidget->setItem(row,3,new QTableWidgetItem(realPath));

        row++;

        dwIndex++;
        len=MAX_PATH;
        dataLen=MAX_PATH;

        traverseResult=RegEnumValue(
                    hkey,dwIndex,valueName,
                    &len,0,&keyType,
                    keyData,&dataLen
                    );
    }

    if(hkey!=nullptr){
        RegCloseKey(hkey);
        qDebug()<<"I an all right";
    }
    ui->tableWidget->resizeColumnsToContents();
    ui->tableWidget->resizeRowsToContents();
}

void MainWindow::viaRegistry(){
    int rowPos=0;


    ui->tableWidget->clear();
    ui->tableWidget->setColumnCount(6);
    ui->tableWidget->setHorizontalHeaderLabels(
                QStringList()<<"Location"<<"name"<<"data"<<"real path"<<"modified time"<<"publisher"
                );
    ui->tableWidget->setRowCount(20);
    viaRegistry1st(rowPos);
    viaRegistry2nd(rowPos);
    viaRegistry3rd(rowPos);
    viaRegistry4th(rowPos);
    viaRegistry5th(rowPos);
    viaRegistry6th(rowPos);
    viaRegistry7th(rowPos);
    viaRegistry8th(rowPos);
    viaRegistry9th(rowPos);
    //仅用于测试
    qDebug()<<"next row id: "<<rowPos;
    ui->tableWidget->resizeColumnsToContents();
    ui->tableWidget->resizeRowsToContents();
}

void MainWindow::viaRegistry1st(int & rowPos){
    //目标:HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
    const WCHAR* subPath=L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";

    //进入目标文件夹
    traverseRegistryUni(HKEY_CURRENT_USER,subPath,rowPos);
}

void MainWindow::viaRegistry2nd(int &rowPos){
//目标:   HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
    const WCHAR* subPath=L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";

    //进入目标文件夹
    traverseRegistryUni(HKEY_LOCAL_MACHINE,subPath,rowPos);
}

void MainWindow::viaRegistry3rd(int &rowPos){
//目标:   HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run
    const WCHAR* subPath=L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run";

    //进入目标文件夹
    traverseRegistryUni(HKEY_LOCAL_MACHINE,subPath,rowPos);
}

void MainWindow::viaRegistry4th(int &rowPos){
//目标:   HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run
    const WCHAR* subPath=L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run";

    //进入目标文件夹
    traverseRegistryUni(HKEY_CURRENT_USER,subPath,rowPos);
}

void MainWindow::viaRegistry5th(int &rowPos){
//目标:   HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
    const WCHAR* subPath=L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce";

    //进入目标文件夹
    traverseRegistryUni(HKEY_LOCAL_MACHINE,subPath,rowPos);
}

void MainWindow::viaRegistry6th(int &rowPos){
//目标:   HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
    const WCHAR* subPath=L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce";

    //进入目标文件夹
    traverseRegistryUni(HKEY_CURRENT_USER,subPath,rowPos);
}

void MainWindow::viaRegistry7th(int &rowPos){
//目标:   HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx
    const WCHAR* subPath=L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx";

    //进入目标文件夹
    traverseRegistryUni(HKEY_LOCAL_MACHINE,subPath,rowPos);
}


void MainWindow::viaRegistry8th(int &rowPos){
    //目标: HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx
    const WCHAR* subPath=L"\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx";
    traverseRegistryUni(HKEY_CURRENT_USER,subPath,rowPos);
}

void MainWindow::viaRegistry9th(int &rowPos){
//目标:   HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
    const WCHAR* subPath=L"SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run";

    //进入目标文件夹
    traverseRegistryUni(HKEY_LOCAL_MACHINE,subPath,rowPos);
}

void MainWindow::traverseRegistryUni(const HKEY root,const WCHAR* const subPath,int & rowPos){
    //记录注册表位置location
    QString location="";
    if(root==HKEY_CURRENT_USER){
        location+="HKCU\\";
    }
    else {
        location+="HKLM\\";
    }
    location+=QString::fromWCharArray(subPath);
    qDebug()<<"Locality: "<<location;


    long openResult;
    HKEY hkey=nullptr;
    openResult=RegOpenKeyExW(
                root,
                subPath,
                0,
                KEY_QUERY_VALUE,
                &hkey
        );

    if(openResult!=ERROR_SUCCESS){
        qDebug()<<"No such location in registry: "<<location;
        if(hkey!=nullptr){
            RegCloseKey(hkey);
        }
        return;
    }

    DWORD dwIndex=0;
    WCHAR valueName[MAX_PATH]={0};
    DWORD len=MAX_PATH;
    BYTE keyData[MAX_PATH]={0};
    DWORD dataLen=MAX_PATH;
    DWORD keyType=REG_SZ;

    long enterResult=RegEnumValueW(
                hkey,dwIndex,valueName,
                &len,0,&keyType,
                keyData,&dataLen
                );



    //遍历目录下所有项目
    while (enterResult==ERROR_SUCCESS) {
        //valueName记录了名称,keyData记录了数据
        QString formalName=QString::fromWCharArray(valueName);
        QString formalData=QString::fromStdWString((LPCTSTR)keyData);
        QString realPath=purePath(formalData);
        QString formalTime=gotoSingleFileTime(realPath);
        QString publiser=publisherName(realPath);
        //仅用于测试
        qDebug()<<"Name: "<<formalName<<" ,data:"<<formalData;
        ui->tableWidget->setItem(rowPos,0,new QTableWidgetItem(location));
        ui->tableWidget->setItem(rowPos,1,new QTableWidgetItem(formalName));
        ui->tableWidget->setItem(rowPos,2,new QTableWidgetItem(formalData));
        ui->tableWidget->setItem(rowPos,3,new QTableWidgetItem(realPath));
        ui->tableWidget->setItem(rowPos,4,new QTableWidgetItem(formalTime));
        ui->tableWidget->setItem(rowPos,5,new QTableWidgetItem(publiser));
        rowPos++;

        dwIndex++;
        len=MAX_PATH;
        dataLen=MAX_PATH;
        enterResult=RegEnumValueW(
                    hkey,dwIndex,valueName,
                    &len,0,&keyType,
                    keyData,&dataLen
                    );
    }

    if(hkey!=nullptr){
        RegCloseKey(hkey);
        qDebug()<<"I am all right";
    }

}

void MainWindow::viaFolderPath(){
    int rowPos=0;
    ui->tableWidget->clear();
    ui->tableWidget->setColumnCount(6);
    ui->tableWidget->setHorizontalHeaderLabels(
            QStringList()<<"location"<<"full name"<<"pure name"<<"suffix"<<"modified time"<<"publisher"
                );
    ui->tableWidget->setRowCount(10);

    //第1个文件夹
    viaFolderPathUser(rowPos);
    //第2个文件夹
    viaFolderPathSys(rowPos);

    //仅用于软件测试
    qDebug("next row: %d",rowPos);

    ui->tableWidget->resizeColumnsToContents();
    ui->tableWidget->resizeRowsToContents();
}

void MainWindow::viaFolderPathSys(int &rowPos){
    //目标文件夹:%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup
    TCHAR targetPath[MAX_PATH]={0};
    ::GetEnvironmentVariableW(L"ProgramData",targetPath,MAX_PATH);
    wcscat_s(targetPath,L"\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*");

    //开始进入文件夹
    traversePathUni(targetPath,rowPos);
}

void MainWindow::viaFolderPathUser(int &rowPos){
    //目标文件夹：%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
    TCHAR targetPath[MAX_PATH]={0};
    ::GetEnvironmentVariableW(L"USERPROFILE",targetPath,MAX_PATH);
    wcscat_s(targetPath,L"\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\*");

    //开始进入文件夹
    traversePathUni(targetPath,rowPos);
}

void MainWindow::traversePathUni(const TCHAR* const target,int &rowpos){
    HANDLE hFind;
    WIN32_FIND_DATAW findFileData;

    //寻找目标文件夹下 第1个文件
    hFind=FindFirstFileW(target,&findFileData);
    if(hFind==INVALID_HANDLE_VALUE){
        qDebug()<<"No such path.";
        return;
    }

    int i=1;
    do{
        //仅用于测试
        qDebug("file name: %ls",findFileData.cFileName);

        QString fullname=QString::fromWCharArray(findFileData.cFileName);
        QString suffix=fullname.split(".").last();

        const int pos=fullname.lastIndexOf(".");
        QString pureName=fullname.left(pos);

        QString refPath=QString::fromWCharArray(target);
        const int tmp=refPath.lastIndexOf("\\");
        refPath=refPath.left(tmp);

        //获得修改日期
        SYSTEMTIME st;
        FileTimeToSystemTime(
                    &findFileData.ftLastWriteTime,
                    &st
                    );
        WCHAR formalTime[MAX_PATH];
        wsprintfW(formalTime,L"%d/%d/%d %d:%d:%d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        QString fileTime=QString::fromWCharArray(formalTime);
        //去除refPath末尾\*
        if(fullname!="."
                &&fullname!=".."
                &&fullname!="desktop.ini"
                ){
            ui->tableWidget->setItem(rowpos,0,new QTableWidgetItem(refPath));
            ui->tableWidget->setItem(rowpos,1,new QTableWidgetItem(fullname));
            ui->tableWidget->setItem(rowpos,2,new QTableWidgetItem(pureName));
            ui->tableWidget->setItem(rowpos,3,new QTableWidgetItem(suffix));
            ui->tableWidget->setItem(rowpos,4,new QTableWidgetItem(fileTime));
            QString singlePath=refPath+"\\"+fullname;

            ui->tableWidget->setItem(rowpos,5,new QTableWidgetItem(publisherName(singlePath)));
            rowpos++;
        }
        //仅用于测试
        //qDebug()<<"full name: "<<fullname<<", pure name: "<<pureName<<", suffix: "<<suffix;
        i++;
    }while (FindNextFileW(hFind,&findFileData));

    FindClose(hFind);
    qDebug()<<"Total file: "<<i-1;
    qDebug()<<"Folder is clear now.";
}

void MainWindow::viaScheduledTasks(){
        //  Initialize COM.
        HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
        if (FAILED(hr))
        {
            qDebug("CoInitialize(multiple) failed: %lx, so we had to quit.", hr);
            hr=CoInitialize(nullptr);
            if(FAILED(hr)){
                qDebug("CoInitialize failed: %lx, so we had to quit.", hr);
                return;
            }
            else {
                qDebug("CoInitialize succeeded, with result=%lx, yes!!!",hr);
            }
        }
        else {
            qDebug("CoInitializeEx(multiple) succeeded, with result=%lx, yes!!!",hr);
        }

        //  Set general COM security levels.
        hr = CoInitializeSecurity(
            nullptr,
            -1,
            nullptr,
            nullptr,
            RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
            RPC_C_IMP_LEVEL_IMPERSONATE,
            nullptr,
            0,
            nullptr);

        if(SUCCEEDED(hr)||hr==RPC_E_TOO_LATE){
            qDebug("CoInitializeSecurity succeeded, with result=%lx, yes!!!",hr);
        }
        else
        {
            qDebug("CoInitializeSecurity failed: %lx, so we have to quit", hr);
            CoUninitialize();
            return;
        }
//        if(FAILED(hr)){
//            qDebug("CoInitializeSecurity failed: %lx", hr);
//        }

        //  Create an instance of the Task Service.
        ITaskService *pService = nullptr;
        hr = CoCreateInstance(CLSID_TaskScheduler,
            nullptr,
            CLSCTX_INPROC_SERVER,
            IID_ITaskService,
            (void**)&pService);
        if (FAILED(hr))
        {
            qDebug("Failed to CoCreate an instance of the TaskService class: %x", hr);
            CoUninitialize();
            return;
        }

        //  Connect to the task service.
        hr = pService->Connect(_variant_t(), _variant_t(),
            _variant_t(), _variant_t());
        if (FAILED(hr))
        {
            qDebug("ITaskService::Connect failed: %x", hr);
            pService->Release();
            CoUninitialize();
            return;
        }


        //  Get the pointer to the root task folder.
        ITaskFolder *pRootFolder = nullptr;
        hr = pService->GetFolder(_bstr_t(L"\\"), &pRootFolder);
        pService->Release();

        if (FAILED(hr))
        {
            qDebug("Cannot get Root Folder pointer: %x", hr);
            CoUninitialize();
            return;
        }

        //  Get the registered tasks in the folder.
        IRegisteredTaskCollection* pTaskCollection = nullptr;
        hr = pRootFolder->GetTasks(0, &pTaskCollection);
        pRootFolder->Release();

        if (FAILED(hr))
        {
            qDebug("Cannot get the registered tasks.: %lx", hr);
            CoUninitialize();
            return;
        }

        LONG numTasks = 0;
        hr = pTaskCollection->get_Count(&numTasks);

        if (numTasks == 0)
        {
            qDebug("No Tasks are currently running.");
            pTaskCollection->Release();
            CoUninitialize();
            return;
        }

        qDebug("Number of Tasks : %d\n", numTasks);

        std::vector<scheduledTaskInfo> result;

        for (LONG i = 0; i < numTasks; i++)
        {
            IRegisteredTask* pRegisteredTask = nullptr;
            pTaskCollection->get_Item(_variant_t(i + 1), &pRegisteredTask);

            BSTR taskName = nullptr;
            pRegisteredTask->get_Name(&taskName);

            TASK_STATE taskState;
            pRegisteredTask->get_State(&taskState);

            ITaskDefinition *itaskdef = nullptr;
            pRegisteredTask->get_Definition(&itaskdef);

            IRegistrationInfo *regInfo = nullptr;
            itaskdef->get_RegistrationInfo(&regInfo);

            BSTR taskInfo = nullptr, author = nullptr;
            regInfo->get_Description(&taskInfo);
            regInfo->get_Author(&author);
            scheduledTaskInfo schdTaskInfo;



            if (taskName) {
                wcscpy_s(schdTaskInfo.name, taskName);
            }
            if (taskInfo) {
                wcscpy_s(schdTaskInfo.description, taskInfo);
            }

            if (author) {
                wcscpy_s(schdTaskInfo.author, author);
            }
            schdTaskInfo.status = taskState;

            itaskdef->Release();
            regInfo->Release();
            pRegisteredTask->Release();

            SysFreeString(taskName);
            SysFreeString(taskInfo);
            SysFreeString(author);
            result.emplace_back(schdTaskInfo);
        }

        ui->tableWidget->clear();
        ui->tableWidget->setColumnCount(4);
        ui->tableWidget->setHorizontalHeaderLabels(
                        QStringList()<<"task's name"<<"author"<<"description"<<"running state"
                    );
        ui->tableWidget->setRowCount(10);

        int row=0;
        for (auto p : result) {
            qDebug("name: %ls, author: %ls,description: %ls, state: %d", p.name, p.author,p.description,p.status);

            QString formalName=QString::fromWCharArray(p.name);
            QString formalAuthor=QString::fromWCharArray(p.author);
            QString formalDescription=QString::fromWCharArray(p.description);
            QString formalState=QString::number(p.status);
            switch (p.status) {
            case (1):formalState+="\tdisabled"; break;
            case (2):formalState+="\tin queue"; break;
            case (3):formalState+="\tready";break;
            case (4):formalState+="\trunning";break;
            default:formalState+="\tunknown";break;
            }

            ui->tableWidget->setItem(row,0,new QTableWidgetItem(formalName));
            ui->tableWidget->setItem(row,1,new QTableWidgetItem(formalAuthor));
            ui->tableWidget->setItem(row,2,new QTableWidgetItem(formalDescription));
            ui->tableWidget->setItem(row,3,new QTableWidgetItem(formalState));
            ++row;
        }

        pTaskCollection->Release();
        CoUninitialize();

        ui->tableWidget->resizeColumnsToContents();
        ui->tableWidget->resizeRowsToContents();
        qDebug()<<"I am all right";
}

void MainWindow::viaServices(){
    HKEY hkeyOuter=nullptr;
    const TCHAR * const rootMenu=_T("SYSTEM\\CurrentControlSet\\Services\\");
    long openResult=::RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                rootMenu,
                0,
                KEY_READ,
                &hkeyOuter
                );
    if(openResult!=ERROR_SUCCESS){
        qDebug()<<"No such target";
        if(hkeyOuter!=nullptr){
            RegCloseKey(hkeyOuter);
        }
        return;
    }

    ui->tableWidget->clear();
    ui->tableWidget->setColumnCount(6);
    ui->tableWidget->setHorizontalHeaderLabels(
                    QStringList()<<"service's name"<<"service's path"<<"run status"<<"real path"<<"modified time"<<"publisher"
                );
    ui->tableWidget->setRowCount(50);
    long remnant=0;
    long key_log=0;
    HKEY hkeyInner=nullptr;
    WCHAR keyData[MAX_PATH]=_T("");
    WCHAR innerFile[MAX_PATH]=_T("");
    DWORD i=0;
    DWORD cbMaxSubKey=MAX_PATH;
    DWORD dwType=MAX_PATH;
    DWORD dwSize=MAX_PATH;

    remnant=RegEnumKeyEx(hkeyOuter,i,innerFile,&cbMaxSubKey,NULL,NULL,NULL,NULL);
    int row=0;
    while (remnant!=ERROR_NO_MORE_ITEMS) {
        //进入子文件夹
        WCHAR ultraPath[MAX_PATH]=_T("");
        wcscat_s(ultraPath,rootMenu);
        wcscat_s(ultraPath,innerFile);
        if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,ultraPath,0,KEY_READ,&hkeyInner)==ERROR_SUCCESS){
            //查询ImagePath
            key_log=RegQueryValueEx(hkeyInner,_T("ImagePath"),NULL,&dwType,(BYTE*)&keyData,&dwSize);
            //查询启动项优先级
            DWORD statusData=0;
            DWORD dwType2=MAX_PATH;
            DWORD dwSize2=MAX_PATH;
            long forStatus=RegQueryValueEx(hkeyInner,_T("Start"),NULL,&dwType2,(BYTE*)&statusData,&dwSize2);
            if(key_log==ERROR_SUCCESS&&forStatus==ERROR_SUCCESS){
                if(wcsstr(keyData, L".exe") != NULL&&statusData<=2){  //后缀为exe的文件，并且是自启动文件
                    //printf("Location: %ls, data: %ls\n", innerFile, (LPCTSTR)keyData);
                    QString formalName=QString::fromWCharArray(innerFile);
                    QString formalData=QString::fromWCharArray(keyData);
                    qDebug()<<"Location: "<<formalName<<", data: "<<formalData;

                    ui->tableWidget->setItem(row,0,new QTableWidgetItem(formalName));
                    ui->tableWidget->setItem(row,1,new QTableWidgetItem(formalData));
                    QString runStatus=QString::number(statusData);
                    switch (statusData) {
                        case 0:runStatus+="\tauto(early)"; break;
                        case 1:runStatus+="\tauto(normal)"; break;
                        default:runStatus+="\tauto(late)"; break;
                    }
                    ui->tableWidget->setItem(row,2,new QTableWidgetItem(runStatus));
                    QString realPath=purePath(formalData);

                    //如果是通过svchost启动，则要查看其他属性
                    if(realPath.contains("svchost.exe",Qt::CaseInsensitive)){
                        //1、进入子文件夹parameters
                        wcscat_s(ultraPath,L"\\Parameters");
                        //qDebug("now path: %ls",ultraPath);
                        HKEY handle2=nullptr;
                        if(RegOpenKeyExW(HKEY_LOCAL_MACHINE,ultraPath,0,KEY_READ,&handle2)==ERROR_SUCCESS){
                            //2、查询文件value： servicdll
                            DWORD dwType2=MAX_PATH;
                            WCHAR dataContent[MAX_PATH]=_T("");
                            DWORD dwSize2=MAX_PATH;
                            //dataContent存的就是服务dll所在路径
                            if(RegQueryValueExW(handle2,_T("ServiceDll"),nullptr,&dwType2,(BYTE*)&dataContent,&dwSize2)==ERROR_SUCCESS){
                                realPath=QString::fromWCharArray(dataContent);
                                realPath=purePath(realPath);
                            }
                        }

                        //3、关闭句柄
                        if(handle2!=nullptr){
                            RegCloseKey(handle2);
                        }
                    }

                    //如果子文件夹查找失败，直接查看Description
                    if(realPath.contains("svchost.exe",Qt::CaseInsensitive)){
                        qDebug()<<"failed, fuck";
                        DWORD dwType2=MAX_PATH;
                        WCHAR dataContent[MAX_PATH]=_T("");
                        DWORD dwSize2=MAX_PATH;
                        key_log=RegQueryValueEx(hkeyInner,_T("Description"),NULL,&dwType2,(BYTE*)&dataContent,&dwSize2);
                        if(key_log==ERROR_SUCCESS){
                            QString formalData2=QString::fromWCharArray(dataContent);
                            const int tmp=realPath.indexOf("svchost.exe",0,Qt::CaseInsensitive);
                            QString currentPath=realPath.left(tmp);
                            realPath=purePath(formalData2);
                            if(formalData2.contains(":")==false&&formalData2.contains("%")==false){
                                qDebug()<<"wocccc!!!";
                                realPath.prepend(currentPath);
                            }
                        }
                     }

                    QString formalTime=gotoSingleFileTime(realPath);
                    ui->tableWidget->setItem(row,3,new QTableWidgetItem(realPath));
                    ui->tableWidget->setItem(row,4,new QTableWidgetItem(formalTime));

                    QString publisher=publisherName(realPath);
                    ui->tableWidget->setItem(row,5,new QTableWidgetItem(publisher));
                    row++;
                }
            }
            if(hkeyInner!=NULL){
                RegCloseKey(hkeyInner);
            }
        }
        ZeroMemory(innerFile,10);
        cbMaxSubKey=MAX_PATH;
        i++;
        remnant=RegEnumKeyEx(hkeyOuter,i,innerFile,&cbMaxSubKey,NULL,NULL,NULL,NULL);
    }

    if(hkeyOuter!=NULL){
        RegCloseKey(hkeyOuter);
        qDebug()<<"I am all right";
    }
    ui->tableWidget->resizeColumnsToContents();
    ui->tableWidget->resizeRowsToContents();
}

void MainWindow::viaDrivers(){
    HKEY hkeyOuter=NULL;
    const WCHAR * const rootMenu=_T("SYSTEM\\CurrentControlSet\\Services\\");
    long openResult=::RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                rootMenu,
                0,
                KEY_READ,
                &hkeyOuter
                );
    if(openResult!=ERROR_SUCCESS){
        qDebug()<<"No such target";
        if(hkeyOuter!=NULL){
            RegCloseKey(hkeyOuter);
        }
        return;
    }

    ui->tableWidget->clear();
    ui->tableWidget->setColumnCount(6);
    ui->tableWidget->setHorizontalHeaderLabels(
                    QStringList()<<"driver's name"<<"drive's path"<<"run status"<<"real path"<<"modified time"<<"publisher"
                );
    ui->tableWidget->setRowCount(150);
    long remnant=NULL;
    long key_log=NULL;
    HKEY hkeyInner=NULL;
    WCHAR keyData[MAX_PATH]=_T("");
    WCHAR innerFile[MAX_PATH]=_T("");
    DWORD i=0;
    DWORD cbMaxSubKey=MAX_PATH;
    DWORD dwType=MAX_PATH;
    DWORD dwSize=MAX_PATH;

    remnant=RegEnumKeyEx(hkeyOuter,i,innerFile,&cbMaxSubKey,NULL,NULL,NULL,NULL);
    int row=0;
    while (remnant!=ERROR_NO_MORE_ITEMS) {
        //进入子文件夹
        WCHAR ultraPath[MAX_PATH]=_T("");
        wcscat_s(ultraPath,rootMenu);
        wcscat_s(ultraPath,innerFile);
        if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,ultraPath,0,KEY_READ,&hkeyInner)==ERROR_SUCCESS){
            //查询ImagePath
            key_log=RegQueryValueEx(hkeyInner,_T("ImagePath"),NULL,&dwType,(BYTE*)&keyData,&dwSize);
            //查询启动项优先级
            DWORD statusData=0;
            DWORD dwType2=MAX_PATH;
            DWORD dwSize2=MAX_PATH;
            long forStatus=RegQueryValueEx(hkeyInner,_T("Start"),NULL,&dwType2,(BYTE*)&statusData,&dwSize2);
            if(key_log==ERROR_SUCCESS&&forStatus==ERROR_SUCCESS){
                if(wcsstr(keyData, L".sys") != NULL&&statusData<=2){  //后缀为sys的文件，并且是自启动文件
                    //printf("Location: %ls, data: %ls\n", innerFile, (LPCTSTR)keyData);
                    QString formalName=QString::fromWCharArray(innerFile);
                    QString formalData=QString::fromWCharArray(keyData);
                    qDebug()<<"Location: "<<formalName<<", data: "<<formalData;

                    ui->tableWidget->setItem(row,0,new QTableWidgetItem(formalName));
                    ui->tableWidget->setItem(row,1,new QTableWidgetItem(formalData));
                    QString runStatus=QString::number(statusData);
                    switch (statusData) {
                        case 0:runStatus+="\tauto(early)"; break;
                        case 1:runStatus+="\tauto(normal)"; break;
                        default:runStatus+="\tauto(late)"; break;
                    }

                    ui->tableWidget->setItem(row,2,new QTableWidgetItem(runStatus));
                    QString realPath=purePath(formalData);
                    QString formalTime=gotoSingleFileTime(realPath);
                    ui->tableWidget->setItem(row,3,new QTableWidgetItem(realPath));
                    ui->tableWidget->setItem(row,4,new QTableWidgetItem(formalTime));

                    QString publisher=publisherName(realPath);
                    ui->tableWidget->setItem(row,5,new QTableWidgetItem(publisher));
                    row++;
                }
            }
            if(hkeyInner!=NULL){
                RegCloseKey(hkeyInner);
            }
        }
        ZeroMemory(innerFile,10);
        cbMaxSubKey=MAX_PATH;
        i++;
        remnant=RegEnumKeyEx(hkeyOuter,i,innerFile,&cbMaxSubKey,NULL,NULL,NULL,NULL);
    }

    if(hkeyOuter!=NULL){
        RegCloseKey(hkeyOuter);
        qDebug()<<"I am all right";
    }
    ui->tableWidget->resizeColumnsToContents();
    ui->tableWidget->resizeRowsToContents();
}


